package com.jie.common.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 正则表达式工具类
 *
 * @author jie
 * @version 1.0
 */
public class RegexUtil {
    /**
     * 手机号正则
     * 支持：
     * 13x、14x、15x、16x、17x、18x、19x
     * 其中 x 是 0-9
     */
    private static final String PHONE_REGEX = "^1[3-9]\\d{9}$";

    /**
     * 固定电话正则
     * 支持格式：
     * 010-1234567
     * 0910-1234567
     * 021-12345678
     */
    private static final String FIXED_PHONE = "^0\\d{2,3}-\\d{7,8}$";

    /**
     * 邮箱正则
     * 支持：
     * test.test@qq.com
     * test.test@qq.com.cn
     */
    private static final String EMAIL_REGEX = "^[a-zA-Z0-9_-]+(?:\\.[a-zA-Z0-9_-]+)*@[a-zA-Z0-9_-]+(?:\\.[a-zA-Z0-9_-]+)+$";

    /**
     * 身份证号正则
     * 支持15位和18位身份证号
     */
    private static final String ID_CARD_REGEX = "(^\\d{15}$)|(^\\d{17}[0-9Xx]$)";

    /**
     * 中文姓名正则
     * 2-10位中文字符
     */
    private static final String CHINESE_NAME_REGEX = "^[\u4e00-\u9fa5]{2,10}$";

    /**
     * 密码强度正则
     * 必须包含数字和字母，可以包含特殊字符，长度8-20
     */
    private static final String PASSWORD_REGEX = "^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d\\W]{8,20}$";

    /**
     * URL正则
     * 支持http、https
     */
    private static final String URL_REGEX = "^(https?://)?([\\da-z.-]+)\\.([a-z.]{2,6})([/\\w .-]*)*/?$";

    /**
     * IPv4地址正则
     */
    private static final String IPV4_REGEX = "^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$";

    /**
     * 邮政编码正则
     */
    private static final String POSTAL_CODE_REGEX = "^[1-9]\\d{5}$";

    /**
     * 银行卡号正则（16-19位数字）
     */
    private static final String BANK_CARD_REGEX = "^\\d{16,19}$";

    /**
     * 统一社会信用代码正则
     */
    private static final String CREDIT_CODE_REGEX = "^[0-9A-HJ-NPQRTUWXY]{2}\\d{6}[0-9A-HJ-NPQRTUWXY]{10}$";

    /**
     * 车牌号正则（支持新能源车牌）
     */
    private static final String LICENSE_PLATE_REGEX = "^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-HJ-NP-Z0-9]{4,5}[A-HJ-NP-Z0-9挂学警港澳]$";

    /**
     * MAC地址正则
     */
    private static final String MAC_REGEX = "^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$";

    /**
     * 中国居民户口簿正则
     */
    private static final String HUKOU_REGEX = "^[0-9]{8,10}$";

    /**
     * 护照号码正则（包含香港、澳门）
     */
    private static final String PASSPORT_REGEX = "^([a-zA-Z]{1,2}\\d{6,10})|([P|p|S|s]\\d{7})|([S|s|G|g|E|e]\\d{8})|([G|g|t|T|S|s|L|l|M|m|K|k]\\d{9})$";

    /**
     * 验证手机号
     */
    public static boolean isPhone(String phone) {
        return isMatch(PHONE_REGEX, phone);
    }

    /**
     * 验证固定电话
     */
    public static boolean isFixedPhone(String phone) {
        return isMatch(FIXED_PHONE, phone);
    }

    /**
     * 验证邮箱
     */
    public static boolean isEmail(String email) {
        return isMatch(EMAIL_REGEX, email);
    }

    /**
     * 验证身份证号
     */
    public static boolean isIdCard(String idCard) {
        return isMatch(ID_CARD_REGEX, idCard);
    }

    /**
     * 验证中文姓名
     */
    public static boolean isChineseName(String name) {
        return isMatch(CHINESE_NAME_REGEX, name);
    }

    /**
     * 验证密码强度
     */
    public static boolean isValidPassword(String password) {
        return isMatch(PASSWORD_REGEX, password);
    }

    /**
     * 验证URL
     */
    public static boolean isUrl(String url) {
        return isMatch(URL_REGEX, url);
    }

    /**
     * 验证IPv4地址
     */
    public static boolean isIpv4(String ipv4) {
        return isMatch(IPV4_REGEX, ipv4);
    }

    /**
     * 验证邮政编码
     */
    public static boolean isPostalCode(String postalCode) {
        return isMatch(POSTAL_CODE_REGEX, postalCode);
    }

    /**
     * 验证银行卡号
     */
    public static boolean isBankCard(String bankCard) {
        return isMatch(BANK_CARD_REGEX, bankCard);
    }

    /**
     * 验证统一社会信用代码
     */
    public static boolean isCreditCode(String creditCode) {
        return isMatch(CREDIT_CODE_REGEX, creditCode);
    }

    /**
     * 验证车牌号
     */
    public static boolean isLicensePlate(String licensePlate) {
        return isMatch(LICENSE_PLATE_REGEX, licensePlate);
    }

    /**
     * 验证MAC地址
     */
    public static boolean isMac(String mac) {
        return isMatch(MAC_REGEX, mac);
    }

    /**
     * 验证户口簿号码
     */
    public static boolean isHukou(String hukou) {
        return isMatch(HUKOU_REGEX, hukou);
    }

    /**
     * 验证护照号码
     */
    public static boolean isPassport(String passport) {
        return isMatch(PASSPORT_REGEX, passport);
    }

    /**
     * 通用的正则验证方法
     */
    public static boolean isMatch(String regex, String input) {
        if (input == null || input.isEmpty()) {
            return false;
        }
        return Pattern.matches(regex, input);
    }

    /**
     * 从字符串中提取手机号
     */
    public static List<String> extractMobiles(String content) {
        return extractMatches(PHONE_REGEX, content);
    }

    /**
     * 从字符串中提取邮箱
     */
    public static List<String> extractEmails(String content) {
        return extractMatches(EMAIL_REGEX, content);
    }

    /**
     * 从字符串中提取URL
     */
    public static List<String> extractUrls(String content) {
        return extractMatches(URL_REGEX, content);
    }

    /**
     * 从字符串中提取IPv4地址
     */
    public static List<String> extractIpv4s(String content) {
        return extractMatches(IPV4_REGEX, content);
    }

    /**
     * 通用的提取匹配内容方法
     */
    private static List<String> extractMatches(String regex, String content) {
        if (content == null || content.isEmpty()) {
            return Collections.emptyList();
        }
        List<String> matches = new ArrayList<>();
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            matches.add(matcher.group());
        }
        return matches;
    }

    /**
     * 替换手机号为指定字符串
     * 例如：将手机号替换为 *******
     */
    public static String maskMobile(String content, String mask) {
        if (content == null || content.isEmpty()) {
            return content;
        }
        return content.replaceAll(PHONE_REGEX, mask);
    }

    /**
     * 替换邮箱为指定字符串
     */
    public static String maskEmail(String content, String mask) {
        if (content == null || content.isEmpty()) {
            return content;
        }
        return content.replaceAll(EMAIL_REGEX, mask);
    }

    /**
     * 替换身份证号为指定字符串
     */
    public static String maskIdCard(String content, String mask) {
        if (content == null || content.isEmpty()) {
            return content;
        }
        return content.replaceAll(ID_CARD_REGEX, mask);
    }

    /**
     * 替换银行卡号为指定字符串
     */
    public static String maskBankCard(String content, String mask) {
        if (content == null || content.isEmpty()) {
            return content;
        }
        return content.replaceAll(BANK_CARD_REGEX, mask);
    }

    /**
     * 通用的掩码方法
     * @param content 原始内容
     * @param start 保留开始位数
     * @param end 保留结束位数
     * @param maskChar 掩码字符
     */
    public static String mask(String content, int start, int end, char maskChar) {
        if (content == null || content.isEmpty()) {
            return content;
        }
        if (start < 0 || end < 0 || start + end > content.length()) {
            return content;
        }
        StringBuilder sb = new StringBuilder();
        sb.append(content.substring(0, start));
        for (int i = 0; i < content.length() - start - end; i++) {
            sb.append(maskChar);
        }
        sb.append(content.substring(content.length() - end));
        return sb.toString();
    }
}